/*****************************************************************
                            Jeu de la vie
Auteur : LE MOAL Olivier pour le projet tutoré
Fonctionnement :
On utilise deux tableaux Tab et Tabn. Tab est le tableau au temps T (avant qu'un cycle d'évolution ai eu lieu)
et Tabn est le résultat de Tab après un cycle d'évolution (temps T+1).
Avant toute chose on s'assure que Tab et Tabn soient identiques, puis on les passe en argument à la fonction Suivant.
Cette fonction compte pour chaque cellule du tableau Tab le nombre des cellules vivantes alentoures, et selon les
règles change l'état de cette cellule dans le tableau Tabn. On ne peut pas modifier l'état de la cellule directement
dans Tab car cela influencerait le nombre de cellules vivantes alentours pour les cases adjacentes qui n'ont pas
encore été traitées.
Après avoir appelé la fonction Suivant, Tabn devient le temps de référence T,
il faut donc que Tab devienne Tabn, puis on peut l'afficher et repartir pour un cycle.

ToDo:
-Libération de la mémoire des tableaux + Gestion d'erreurs pour l'import/export
******************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "fonctions.h"

int main(int argc, char **argv)
{

    int size=-1; //taille de la grille (size*size)
    int **Tab, **Tabn = NULL; //grilles t et t+1
    int birth[8]; //tableau qui stock les règles de naissance
    int death[8]; //tableau qui stock les règles de mort
    int i,j; //compteurs de boucle
    char value = ' '; //choix utilisateur dans les menus
    int cyclique = 1; //règle fonctionnement du tableau
    int succes; //stock la valeur de retour des fonctions import/export (1 si l'execution a réussie sinon 0)
    int option_birth; //choix de l'utilisateur pour rajouter une règle de naissance
    int option_death; //choix de l'utilisateur pour rajouter une règle de mort

    for (i=0;i<=8;i++)
    {
        death[i]=0;
        birth[i]=0;
    }

    death[2]=1;
    death[3]=1;
    birth[3]=1; //règles par défaut

    printf("Bienvenue sur le jeu de la vie\n");
    while( size<1 || size>50)
    {
        printf("Veuillez entrer la taille souhaitee de la grille : ");
        scanf("%d",&size);
        purger();
        if(size<1 || size>50) printf("\nTaille incorrecte\n");
    }

    Tab = (int **)malloc(size * sizeof(int*));
    Tabn = (int **)malloc(size * sizeof(int*));
    if (Tab==NULL || Tabn==NULL) exit(0);
    for(i=0; i<size ;i++)
    {
        Tab[i] = (int *)calloc (size, sizeof(int));
        Tabn[i] = (int *)calloc (size, sizeof(int));
        if (Tab[i]==NULL || Tabn[i]==NULL) exit(1);
    } //on alloue mémoire nécessaire au tableau de dimension size*size

    Aleatoire(Tab,size);//on remplie le tableau aléatoirement avec des cellules mortes ou vivantes et on l'affiche

    while (value!='q')
    {          
        CHANGEMODE1;
        _kbhit(); //saisie non bloquante de l'utilisateur, mais ne marche que sous windows...
        value=GETCH(); //value prend pour valeur la saisie de l'utilisateur
        CHANGEMODE0;

        switch(value)
        {
        case ('n') :
            Step(Tab,Tabn,size,birth,death,cyclique);
            break; //Effectue un cycle d'évolution
       

        case ('l') :  //déroulement en continue, tant que l'utilisateur ne stop pas en appuyant sur 's'
            CHANGEMODE1;
            while(value!='s')
            {
                if(_kbhit()) //saisie non bloquante
                {
                    value=GETCH();
                }
                Step(Tab,Tabn,size,birth,death,cyclique);
            }
            CHANGEMODE0;
            break;

        case ('g') :
            Aleatoire(Tab,size);
            break; //génère une nouvelle grille aléatoire

        case ('o') : //affiche les options
            while (value!='4'){
                Options(death,birth,cyclique);
                scanf("%c",&value);
                purger();
                switch(value)
                {
                case('2') :
                    printf("\nVeuillez entrez la valeur pour laquelle vous souhaitez ajuster le nombre de cellules allentours en vie nécessaire a la survie d'une cellule : ");
                    scanf("%d",&option_death);
                    if (option_death>=0 && option_death<=8)
                    {
                        if (death[option_death]==1){death[option_death]=0;} else {death[option_death]=1;}
                    }
                    break;

                case('1') :
                   
                    printf("\nVeuillez entrez la valeur pour laquelle vous souhaitez ajuster le nombre de cellules allentours en vie nécessaire a la naissance d'une cellule : ");
                    scanf("%d",&option_birth);
                    if (option_birth>=0 && option_birth<=8)
                    {
                        if (birth[option_birth]==1)
                        {
                            birth[option_birth]=0;
                        }
                        else
                        {
                            birth[option_birth]=1;
                        }
                    }
                    break;
                   

                case('3') :
                    if (cyclique==1)
                    {
                        cyclique=0;
                    }
                    else
                    {
                        cyclique=1;
                    }
                    break;
                   
                }
            }
            Interface(Tab,size);
            break;

        case ('v'): //remplie la grille de cellules mortes
            for (i=0; i<=size-1; i++)
            {
                for (j=0; j<=size-1;j++)
                {
                    Tab[i][j]=0;
                }
            }
            Interface(Tab,size);
            break;


        case ('e') : //passe en mode édition
            i=0;j=0; //on met i et j à 0 pour s'assurer de pouvoir rentrer dans la boucle
            while(i!=-1 && j!=-1)
            {
                printf("\nEntrez les coordonnees de la cellule dont vous souhaitez changer l'etat : (0 pour sortir)\n");
                printf("largeur ? ");scanf("%d",&j);purger();
                printf("hauteur ? ");scanf("%d",&i);purger();
                if (j<=size && i<=size && j>0 && i>0)
                {
                    i--;j--;
                    if (Tab[i][j]==0)
                    {
                        Tab[i][j]=1;
                    }
                    else
                    {
                        Tab[i][j]=0;
                    }
                    Interface(Tab,size);
                }
                else if (i==0 || j==0)
                {
                    i--;j--;Interface(Tab,size);
                }
                else {
                    Interface(Tab,size);printf("\nCoordonnees incorrectes");
                }
            }
            break;


        case ('x') : //exporte le tableau dans un fichier
            succes = -1;
            if((succes = Exporter(Tab,size))==0)
            {
                Interface(Tab,size);
                printf("Tableau exporte !");
            }
            else
            {
                printf("Erreur lors de l'export\n");
            }
            break;


        case ('i'): //importe le tableau
            succes = -1;
            if ((succes = Importer(Tab,size))==0)
            {
                Interface(Tab,size);
            }
            else {
                printf("Erreur lors de l'import\n");
            }
            break;
        }
    }
    free(Tab);
    free(Tabn); //on libère la mémoire
    return 0;
}



